﻿using Dispatch.DispatchData;
using Dispatch.Model;
using Dispatch.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Dispatch.Receive
{
    /// <summary>
    /// 传输坞的事件调度
    /// </summary>
    internal class DispatchDevice
    {
        internal async void Dispatch (string IP,byte[] Data )
        {
            string? DeviceType = DeviceMountSet.GetDeviceType(IP);
            if (DeviceType == null) return; //代码或者配置问题

            IDeviceEvent? deviceEvent = DeviceFactory.GetDevice(DeviceType);
            if (deviceEvent == null)
            {
                //没有解析类
                return;
            }

            DeviceReceiveData? receiveData = deviceEvent.ResolveData(IP, Data);
            if (receiveData == null)
            {
                //解析失败
                return;
            }
           

            DeviceModel? device = DeviceMountSet.GetDevice(IP, receiveData.Value.DockNum);
            if (device == null)
            {
                return;
            }
            int agvid;
            byte[] buf;

            //记录日志，用于监控
            _=DeviceMountSet.SaveLog(device.DeviceID,receiveData.Value);
           
            switch (receiveData.Value.Cmd)
            {
                case DeviceCmdEnum.物料信息:
                    _ = DeviceMountSet.UpdateDeviceMountAsync(device.DeviceID, device.Process, receiveData.Value);
                    break;
                case DeviceCmdEnum.检测AGV传输状态:
                    //直接告之AGV已经准备好  
                    buf = deviceEvent.AgvTransReady(device.DockNum);
                    _ = Tools.SendDataToDeviceAsync(device.SendPort, device.IP, device.Port, buf);
                     
                    break;
                case DeviceCmdEnum.需要出料:
                    //通知AGV收料
                    agvid = await DeviceMountSet.GetAgv(device.DeviceID);
                    if (device.UpOut)
                    {
                        //传输坞上层出料，AGV上层收料
                        buf = AgvEvent.TransUp(agvid, true);
                    }
                    else
                    {
                        //传输坞下层出料，AGV下层收料
                        buf = AgvEvent.TransDown(agvid, true);
                    }
                    _ = AgvDataSet.SendToAgvAsync(agvid, buf);
                    break;
                case DeviceCmdEnum.需要入料:
                    //通知AGV出料
                    agvid = await DeviceMountSet.GetAgv(device.DeviceID);
                    if (device.DownOut)
                    {
                        //传输坞下层出料 ,上层入料，AGV上层出料
                        buf = AgvEvent.TransUp(agvid, false);
                    }
                    else
                    {
                        //传输坞上层出料,下层入料，AGV下层出料
                        buf = AgvEvent.TransDown(agvid, true);
                    }
                    _ = AgvDataSet.SendToAgvAsync(agvid, buf);
                    break;
                case DeviceCmdEnum.同时进出料:
                    agvid = await DeviceMountSet.GetAgv(device.DeviceID);
                    if (device.UpOut)
                    {
                        //传输坞上出，AGV 上入下出
                        buf = AgvEvent.TransBoth(agvid, UpOut: false);
                    }
                    else
                    {
                        //上出下入
                        buf = AgvEvent.TransBoth(agvid, UpOut: true);
                    }
                    _ = AgvDataSet.SendToAgvAsync(agvid, buf);
                    break;
                case DeviceCmdEnum.通知AGV离开:
                    //注意，此处需要细化
                    agvid = await DeviceMountSet.GetAgv(device.DeviceID);
                    buf = AgvEvent.TransFinish(agvid);
                    _ = AgvDataSet.SendToAgvAsync(agvid, buf);
                    break;
                case DeviceCmdEnum.异常:
                    agvid = await DeviceMountSet.GetAgv(device.DeviceID);
                    buf = AgvEvent.TransStop(agvid);
                    _ = AgvDataSet.SendToAgvAsync(agvid, buf);
                    break;
            }
        }
    }
}
